package com.googlecode.microanalyst.designer.figures;

import org.eclipse.draw2d.AbstractConnectionAnchor;
import org.eclipse.draw2d.IFigure;
import org.eclipse.draw2d.ScalableFigure;
import org.eclipse.draw2d.geometry.Point;
import org.eclipse.draw2d.geometry.PrecisionPoint;
import org.eclipse.draw2d.geometry.Rectangle;

public class FixedConnectionAnchor extends AbstractConnectionAnchor {

	enum Corner {
		LEFT, RIGHT, TOP, BOTTOM
	}

	public static final Corner LEFT = Corner.LEFT, RIGHT = Corner.RIGHT, TOP = Corner.TOP, BOTTOM = Corner.BOTTOM;

	private int offsetX;
	private int offsetY;
	private final Corner referenceCorner;

	public FixedConnectionAnchor(IFigure owner, Corner referenceCorner,
			int offsetX, int offsetY) {
		super(owner);
		this.offsetX = offsetX;
		this.offsetY = offsetY;
		this.referenceCorner = referenceCorner;
	}

	public FixedConnectionAnchor(IFigure owner, int offsetX, int offsetY) {
		this(owner, Corner.LEFT, offsetX, offsetY);
	}

	/**
	 * @see org.eclipse.draw2d.AbstractConnectionAnchor#ancestorMoved(IFigure)
	 */
	public void ancestorMoved(IFigure figure) {
		if (figure instanceof ScalableFigure)
			return;
		super.ancestorMoved(figure);
	}

	public Point getLocation(Point reference) {
		Rectangle r = getOwner().getBounds();
		int x = 0, y = 0;
		switch (referenceCorner) {
		case TOP:
			x = r.right() - 1 - offsetX;
			y = r.y + offsetY;
			break;
		case BOTTOM:
			x = r.right() - 1 - offsetX;
			y = r.bottom() - 1 - offsetY;
			break;
		case LEFT:
			x = r.x + offsetX;
			y = r.bottom() - 1 - offsetY;
			break;
		case RIGHT:
			x = r.right() - 1 - offsetX;
			y = r.bottom() - 1 - offsetY;
			break;
		}

		Point p = new PrecisionPoint(x, y);
		getOwner().translateToAbsolute(p);
		return p;
	}

	public Point getReferencePoint() {
		return getLocation(null);
	}

	/**
	 * @param offsetH
	 *            The offsetH to set.
	 */
	public void setOffsetH(int offsetH) {
		this.offsetX = offsetH;
		fireAnchorMoved();
	}

	/**
	 * @param offsetV
	 *            The offsetV to set.
	 */
	public void setOffsetV(int offsetV) {
		this.offsetY = offsetV;
		fireAnchorMoved();
	}

	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + offsetX;
		result = prime * result + offsetY;
		result = prime * result
				+ ((referenceCorner == null) ? 0 : referenceCorner.hashCode());
		return result;
	}

	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		FixedConnectionAnchor other = (FixedConnectionAnchor) obj;
		if (offsetX != other.offsetX)
			return false;
		if (offsetY != other.offsetY)
			return false;
		if (referenceCorner != other.referenceCorner)
			return false;
		return true;
	}
}
